package dm.ast;

import test.envset.GlobalState;

import java.sql.Array;
import java.util.ArrayList;
import java.util.List;

/**
 * Dm的IN表达式
 */
public class DmInExpression extends DmBoolExpression{
    List<DmExpression> expsLeft = new ArrayList<>();  //左操作数
    List<List<DmExpression>> expsRight = null;  //右操作数

    public DmInExpression() {
        this.op = new DmBoolOperator();
        this.op.setOperator("IN");
    }

    //右表达式
    public void addInrigExp(List<DmExpression> arr){
        if(expsRight == null){
            expsRight = new ArrayList<List<DmExpression>>();
        }
        expsRight.add(arr);
    }

    //左表达式
    public void addInLeftExp(DmExpression exp){
        if(expsLeft == null){
            expsLeft = new ArrayList<DmExpression>();

        }
        expsLeft.add(exp);
    }

    @Override
    public void setWidt(){
        if(expsLeft == null){
            wid_t = 3;
        } else {
            wid_t = 1;
            for (int i = 0; i < expsLeft.size(); i++) {
                expsLeft.get(i).setWidt();
                wid_t += expsLeft.get(i).getWidt();
            }
            if(expsRight != null){
                for (int i = 0; i < expsRight.size(); i++) {
                    for (int j = 0; j < expsLeft.size(); j++) {
                        expsRight.get(i).get(j).setWidt();
                        wid_t += expsRight.get(i).get(j).getWidt();

                    }
                }
            }
        }
    }

    @Override
    public void setDept(){
        if(expsLeft == null){
            dep_t = 1;
        }else{
            for (int i = 0; i < expsLeft.size(); i++) {
                expsLeft.get(i).setDept();
                dep_t = expsLeft.get(i).getDept();
            }
            if(expsRight != null){
                int tmp_dept = dep_t;
                for (int i = 0; i < expsRight.size(); i++) {
                    for (int j = 0; j < expsLeft.size(); j++) {
                        expsRight.get(i).get(j).setDept();
                        tmp_dept = expsRight.get(i).get(j).getDept();
                        if(tmp_dept > dep_t){
                            dep_t = tmp_dept;
                        }
                    }
                }
            }
        }

    }

    @Override
    public String toSql(){
        if(expsLeft == null || expsRight.get(0) == null){
            return " " + this.getClass().getSimpleName() + getSqlTarget();
        }else {
            StringBuilder sql = new StringBuilder();
            sql.append(" ");

            StringBuilder tmpSql1 = new StringBuilder();
            tmpSql1.append(expsLeft.get(0).toSqlClose());
            for (int i = 1; i < expsLeft.size(); i++) {
                tmpSql1.append(",");
                tmpSql1.append(expsLeft.get(i).toSqlClose());
            }
            sql.append(stringClose(tmpSql1.toString()));
            if(notFlag == true){
                sql.append(" NOT");
            }
            sql.append(op.toSql());
            StringBuilder tmpSql = new StringBuilder();
            if(expsLeft.size() == 1){
                sql.append(String.format("/*w:%d*/" , expsRight.size() * expsLeft.size()));
                tmpSql.append(expsRight.get(0).get(0).toSqlClose());
                for (int i = 1; i < expsRight.size(); i++) {
                    tmpSql.append(",");
                    tmpSql.append(expsRight.get(i).get(0).toSqlClose());
                }
            }else {
                sql.append(String.format("/*wid:%d* *column:%d*/" , expsRight.size() * expsLeft.size() , expsLeft.size()));
                for (int i = 0; i < expsRight.size(); i++) {
                    StringBuilder tmpSql2 = new StringBuilder();
                    for (int j = 0; j < expsLeft.size(); j++) {
                        tmpSql2.append(expsRight.get(i).get(j).toSqlClose());
                        if(j != (expsLeft.size() - 1)){
                            tmpSql2.append(",");
                        }
                    }
                    tmpSql.append(stringClose(tmpSql2.toString()));
                    if( i != (expsRight.size() -1 )){
                        tmpSql.append(",");
                    }
                }
            }
            sql.append(stringClose(tmpSql.toString()));
            return sql.toString();
        }
    }

    @Override
    public void fill(GlobalState globalState){
        if(!isCompleted){
            //左操作数填充
            for (int i = 0; i < expsLeft.size(); i++) {
                expsLeft.get(i).fill(globalState);
            }
            //右操作数填充
            for (int i = 0; i < expsRight.size(); i++) {
                for (int j = 0; j < expsLeft.size(); j++) {
                    expsRight.get(i).get(j).fill(globalState);
                }
            }
            isCompleted = true;
        }
    }


    //处理sql错误
    //-4097 | 单行子查询返回多行
    @Override
    public void fixErr4097(){
        for (int i = 0; i < expsLeft.size(); i++) {
            fixErr4097Low(expsLeft.get(i));
        }

        for (int i = 0; i < expsRight.size(); i++) {
            for (int j = 0; j < expsLeft.size(); j++) {
                fixErr4097Low(expsRight.get(i).get(j));
            }
        }
    }
}
